detached metadata: Put these in transaction
authorAlexander Larsson <alexl@redhat.com>
Fri, 21 Oct 2016 10:10:30 +0000 (12:10 +0200)
committerAtomic Bot <atomic-devel@projectatomic.io>
Fri, 21 Oct 2016 10:50:41 +0000 (10:50 +0000)
If there is a transaction active, then we put writes to detached
metadata into the staging dir, and when reading it we look there
first. This allows transactions to be aborted half-way without
writing the detached metadata into the repository (possibly
overwriting any old metadata from there).

This fixes https://github.com/ostreedev/ostree/issues/526

Closes: #539
Approved by: giuseppe

src/libostree/ostree-repo-commit.c

index 3d8008f7a886a860b5c2bb13121c676708797a88..42e064002309fdc93cfb3c82e334b0eb640d19c4 100644 (file)
@@ -2035,8 +2035,18 @@ ostree_repo_read_commit_detached_metadata (OstreeRepo      *self,
   g_autoptr(GVariant) ret_metadata = NULL;
 
   _ostree_loose_path (buf, checksum, OSTREE_OBJECT_TYPE_COMMIT_META, self->mode);
-  
-  if (!ot_util_variant_map_at (self->objects_dir_fd, buf,
+
+  if (self->commit_stagedir_fd != -1 &&
+      !ot_util_variant_map_at (self->commit_stagedir_fd, buf,
+                               G_VARIANT_TYPE ("a{sv}"),
+                               OT_VARIANT_MAP_ALLOW_NOENT | OT_VARIANT_MAP_TRUSTED, &ret_metadata, error))
+    {
+      g_prefix_error (error, "Unable to read existing detached metadata: ");
+      goto out;
+    }
+
+  if (ret_metadata == NULL &&
+      !ot_util_variant_map_at (self->objects_dir_fd, buf,
                                G_VARIANT_TYPE ("a{sv}"),
                                OT_VARIANT_MAP_ALLOW_NOENT | OT_VARIANT_MAP_TRUSTED, &ret_metadata, error))
     {
@@ -2079,10 +2089,16 @@ ostree_repo_write_commit_detached_metadata (OstreeRepo      *self,
   g_autoptr(GVariant) normalized = NULL;
   gsize normalized_size = 0;
   const guint8 *data = NULL;
+  int dest_dfd;
+
+  if (self->in_transaction)
+    dest_dfd = self->commit_stagedir_fd;
+  else
+    dest_dfd = self->objects_dir_fd;
 
   _ostree_loose_path (pathbuf, checksum, OSTREE_OBJECT_TYPE_COMMIT_META, self->mode);
 
-  if (!_ostree_repo_ensure_loose_objdir_at (self->objects_dir_fd, checksum,
+  if (!_ostree_repo_ensure_loose_objdir_at (dest_dfd, checksum,
                                             cancellable, error))
     return FALSE;
 
@@ -2096,7 +2112,7 @@ ostree_repo_write_commit_detached_metadata (OstreeRepo      *self,
   if (data == NULL)
     data = (guint8*)"";
 
-  if (!glnx_file_replace_contents_at (self->objects_dir_fd, pathbuf,
+  if (!glnx_file_replace_contents_at (dest_dfd, pathbuf,
                                       data, normalized_size,
                                       0, cancellable, error))
     {